<?php
import("core.com.indicator.Indicator");
import("core.com.indicator.AbstractIndicatorSupport");

/**
 * KDJ
 * @author w.
 *
 */
class Kdj extends AbstractIndicatorSupport implements Indicator {

    const KEY = 'kdj';
    
	const KDJ_K = 'kdj_k';
	const KDJ_D = 'kdj_d';
	const KDJ_J = 'kdj_j';
	
    private $length;
    private $lowLength;
    private $moothLength;
    
    public function __construct($length,$lowLength,$moothLength,$collection = null){
        $this->length = $length;
        $this->lowLength = $lowLength;
        $this->moothLength = $moothLength;
        if($collection != null){
		    $this->collection = $collection;
		}
    }
	
    public function calc($bars){
        $bars = $this->getSupplyBars($bars, $this->length);
        $cnt = count($bars)-1;
        $rsv = array();
        $hIndex = 0;
        $lIndex = 0;
        $prev_index = 0;
        for($i=0;$i<=$cnt;$i++){
            if(array_key_exists(self::KDJ_K,$bars[$i]))continue;
            $hlDif = AlgFunc::highest($bars,$this->length,$i,$hIndex)-AlgFunc::lowest($bars,$this->length,$i,$lIndex);
            if($hlDif==0){
                $rsv[$i] = 0;
            } else {
                $rsv[$i] = round(($bars[$i][CLOSE]-AlgFunc::lowest($bars,$this->length,$i,$lIndex))/$hlDif*100,2);
            }
            if($i==0){
                $bars = $this->setBarData(self::KDJ_K, 50, $bars, $i);
                $bars = $this->setBarData(self::KDJ_D, 50, $bars, $i);
                $bars = $this->setBarData(self::KDJ_J, 50, $bars, $i);
            } else {
                $prev_index = $i-1;
                if(!array_key_exists(self::KDJ_K,$bars[$prev_index])){
                    $bars[$prev_index][self::KDJ_K] = 50;
                    $bars[$prev_index][self::KDJ_D] = 50;
                }
                $kVal = AlgFunc::getSma($rsv[$i],$bars[$prev_index][self::KDJ_K],$this->lowLength,1);
                $dVal = AlgFunc::getSma($kVal,$bars[$prev_index][self::KDJ_D],$this->moothLength,1);
                $jVal = 3*$kVal - 2*$dVal;
                $bars = $this->setBarData(self::KDJ_K, $kVal, $bars, $i);
                $bars = $this->setBarData(self::KDJ_D, $dVal, $bars, $i);
                $bars = $this->setBarData(self::KDJ_J, $jVal, $bars, $i);
            }
        }
        return $bars;
	}
	
	public function save($bars){
		$cnt = count($bars);
		// 获取保存的键值
		$total = 0;
		for($i=0;$i<$cnt;$i++){
			// 保存到数据库
		    if($this->saveDB(self::KDJ_K,$bars[$i])
		        && $this->saveDB(self::KDJ_D,$bars[$i])
		        && $this->saveDB(self::KDJ_J,$bars[$i])
		        ){
		            $total++;
		    }
		}
		info($this->getKey().':成功更新'.$total.'条');
		return $bars;
	}

	private function getKey(){
	    return self::KEY;
	}
}

?>
